﻿using System;
using System.Collections.Specialized;
using System.Threading;
using System.Web.Mvc;
using System.Web.Security;
using AgileBoard.Domain;
using AgileBoard.Dtos;
using AgileBoard.Dtos.Mappers;

namespace AgileBoard.Web.Controllers
{
    public class BaseController : Controller
    {
        public AllManagerFactory ManagerFactory
        {
            get
            {
                // This will not work for MVC framework but is instead provided for ease
                // of unit testing this type. See the comments at the end of this file for more
                // information.
                if (ControllerContext.HttpContext.Items["ManagerFactory"] != null)
                {
                    BaseDTOMapper.Manager = (AllManagerFactory) ControllerContext.HttpContext.Items["ManagerFactory"];
                    return ControllerContext.HttpContext.Items["ManagerFactory"] as AllManagerFactory;
                }
                else if (CurrentUser != null && CurrentUser.Project.Name == "demo")
                {
                    if (Session["ManagerFactory"] == null) Session["ManagerFactory"] = DemoData.ManagerFactory;
                    BaseDTOMapper.Manager = (AllManagerFactory) Session["ManagerFactory"];
                    return (AllManagerFactory) Session["ManagerFactory"];
                }

/*
                BaseDTOMapper.Manager = null;
                var webApplicationContext = ContextRegistry.GetContext();

                var manager = webApplicationContext.GetObject("ManagerFactory") as AllManagerFactory;
*/
                throw new InvalidOperationException("Add to ioc the AllManagerFactory ");
                return null;
            }
        }


        public IFormsAuthentication FormsAuth { get; set; }

        public IMembershipService MembershipService { get; set; }

        public virtual User CurrentUser
        {
            get
            {
                var user = ControllerContext.HttpContext.User as User;
                //if (user == null) throw new ApplicationException("HttpContext.User is not a VisualAgile.Model.User");
                return user;
            }
        }

        public virtual NameValueCollection Form
        {
            get
            {
                if (Request.RequestType == "POST")
                {
                    return Request.Form;
                }
                else
                {
                    return Request.QueryString;
                }
            }
        }

        public void CreateLabels(DateTime fromDate, Guid parentId)
        {
            for (int i = 1; i < 15; i++)
            {
                if (i > 1) fromDate = fromDate.AddDays(1);
                Label label = ManagerFactory.LabelManager.NewLabel();

                label.Date = fromDate.ToShortDateString();
                label.IterationID = parentId.ToString();
                ManagerFactory.LabelManager.Save(label);
            }
        }

        [NonAction]
        public virtual void SetAuthenticationCookie(string email)
        {
            FormsAuth.SignIn(email, true);
        }

        [NonAction]
        public virtual void SetContextUserTo(User user)
        {
            Thread.CurrentPrincipal = ControllerContext.HttpContext.User = user;
        }

        [NonAction]
        public virtual void SetContextManagerTo(AllManagerFactory manager)
        {
            Session["ManagerFactory"] = manager;
        }


        [NonAction]
        public virtual void RemoveAuthenticationCookie()
        {
            FormsAuth.SignOut();
        }

        #region Nested type: AccountMembershipService

        public class AccountMembershipService : IMembershipService
        {
            private readonly MembershipProvider _provider;

            public AccountMembershipService()
                : this(null)
            {
            }

            public AccountMembershipService(MembershipProvider provider)
            {
                _provider = provider ?? Membership.Provider;
            }

            #region IMembershipService Members

            public int MinPasswordLength
            {
                get { return _provider.MinRequiredPasswordLength; }
            }

            public bool ValidateUser(string userName, string password)
            {
                return _provider.ValidateUser(userName, password);
            }

            public MembershipCreateStatus CreateUser(string userName, string password, string email)
            {
                MembershipCreateStatus status;
                _provider.CreateUser(userName, password, email, null, null, true, null, out status);
                return status;
            }

            public bool ChangePassword(string userName, string oldPassword, string newPassword)
            {
                MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
                return currentUser.ChangePassword(oldPassword, newPassword);
            }

            #endregion
        }

        #endregion

        #region Nested type: FormsAuthenticationService

        public class FormsAuthenticationService : IFormsAuthentication
        {
            #region IFormsAuthentication Members

            public void SignIn(string userName, bool createPersistentCookie)
            {
                FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
            }

            public void SignOut()
            {
                FormsAuthentication.SignOut();
            }

            #endregion
        }

        #endregion

        #region Nested type: IFormsAuthentication

        public interface IFormsAuthentication
        {
            void SignIn(string userName, bool createPersistentCookie);
            void SignOut();
        }

        #endregion

        #region Nested type: IMembershipService

        public interface IMembershipService
        {
            int MinPasswordLength { get; }

            bool ValidateUser(string userName, string password);
            MembershipCreateStatus CreateUser(string userName, string password, string email);
            bool ChangePassword(string userName, string oldPassword, string newPassword);
        }

        #endregion
    }
}